/*
 * Copyright (c) 2025 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef HMFS_COMMAND_H
#define HMFS_COMMAND_H

#include <string>
#include <sys/types.h>
#include <map>
#include <unistd.h>
#include <vector>
#include <functional>

namespace OHOS {
namespace Hmfs {

// enum class CmdFunc {
//     MKFS,
//     RESIZE,
// };

typedef struct CmdConfig {
    int func;
    bool heapBasedAllocation = false;
    bool forceOverwrite = false;
    bool zonedMode = false;
    std::vector<std::string> deviceList;
    int32_t debugLevel = 0;
    uint64_t wantedSectorSize = std::numeric_limits<uint64_t>::max();
    uint64_t wantedSectorCount = std::numeric_limits<uint64_t>::max();
    uint32_t features = 0;
    uint32_t segsPerSection = 1;
    uint32_t sectionsPerZone = 1;
    double overProvision = 0.0;
    std::vector<std::string> coldExtList;
    std::vector<std::string> hotExtList;
    std::string volume;
    int32_t force = 0;
    int32_t safeResize = 0;
    int32_t largeNatBitmap = 0;
    uint16_t sEncoding = 0;
    uint16_t sEncodingFlags = 0;
    double newOverprovision;
    uint32_t rootUid = getuid();
    uint32_t rootGid = getgid();
    bool sparseMode = false;
    uint64_t deviceSize = 0;
    uint64_t targetSectors = 0;
    uint32_t quotaBits;
    bool trim = true;
    uint32_t defaultOptionSet = 0;
    bool fakeSeed = false;
    uint32_t timeStamp = std::numeric_limits<uint32_t>::max();
    std::string uuid;

} CmdConfig;

enum class ArgParseResult {
    OK = 0,
    FINISH,
    ERROR,
};

class CmdParser {
public:
    CmdParser(CmdConfig& cmdPara) : cfgPara_(cmdPara) {}
    ~CmdParser() = default;
    int32_t ParseOption(int32_t argc, char *argv[]);
    virtual void ShowCmdUsage() = 0;
    using HandleArgValue = std::function<ArgParseResult(const std::string&)>;
    void RegCmdOption(char option, bool hasPara, HandleArgValue handle);
    ArgParseResult ProcessOption(char option, const std::string &argValue);
    ArgParseResult ProcessCasefolding(const std::string& argValue);
    ArgParseResult ProcessDebugLevel(const std::string& argValue);
    ArgParseResult ProcessFeatures(const std::string& argValue);
    ArgParseResult ProcessOverProvision(const std::string& argValue);
    ArgParseResult ProcessLargeNatBitmap(const std::string& argValue);

    CmdConfig& GetCmdConfig()
    {
        return cfgPara_;
    }
    static CmdParser* GetSingleton()
    {
        return instance_;
    }

protected:
    CmdConfig& cfgPara_;
    static void RegisterSingleton(CmdParser* instance)
    {
        instance_ = instance;
    }

private:
    std::map<char, HandleArgValue> handles_;
    std::string optionString_;
    static CmdParser* instance_;
};

} // namespace Hmfs
} // namespace OHOS
#endif
